home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i081: Phase of the moon, date routines
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: Jef Poskanzer <unisoft!charming>
- Mod.sources: Volume 8, Issue 81
- Archive-name: phoon
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README Makefile deltime.c deltime.man dtime.c dtimep.lex lexedit.sed
- # lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h
- # This archive created by
- # Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(2571 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^X//' << \SHAR_EOF > 'README'
- XSecond distribution of phoon, deltime, and libtws - 24feb87.
- X
- X
- XThis package contains two programs and a library:
- X
- X phoon - program to display the PHase of the mOON. Unlike other
- X such programs, which just tell you how long since first quarter
- X or something like that, phoon *shows* you the phase with a little
- X picture. I've put an example at the end of this file. I first
- X wrote this program in Pascal / TOPS-20 at CMU in 1979; I translated
- X it to Ratfor / Software Tools in 1981; and now it's in C / Unix*.
- X
- X deltime - program to subtract date/times. Tells you the difference
- X between two date/times, or between now and a specified date/time.
- X I once used this to help a friend quit smoking - every time she
- X logged in, the computer told her how many days since her last
- X cigarette. I also use it in my .login, to tell me how old I am.
- X
- X libtws - date/time library. Unlike the standard Unix*
- X date/time routines, libtws lets you parse a date/time string
- X into internal form. Most of this library came from version
- X 6.5 of the MH message handling system, courtesy of Marshall Rose.
- X I extended it somewhat and added the manual entry.
- X
- X
- XFiles in this distribution:
- X
- X README this
- X Makefile guess
- X deltime.c source for time subtraction tool
- X deltime.man manual for time subtraction tool
- X dtime.c source for most of the time routines
- X dtimep.lex source for time-parsing routine
- X lexedit.sed script to modify output of lex
- X lexstring.c front end for time-parsing routine
- X libtws.man manual for time library
- X parsetime.c source for test program
- X phoon.c source for phase of moon program
- X phoon.man manual for phase of moon program
- X tws.h include file for time library
- X
- X
- XUnpack the files, edit Makefile and change the options to suit,
- Xmake, and enjoy! I've tested this stuff under 4.2 BSD, 4.3 BSD,
- Xand System V rel 2. Nevertheless, I'm sure bugs remain. Feedback
- Xis welcome - send bug reports, enhancements, checks, money orders,
- Xetc. to the addresses below.
- X
- X
- X Jef Poskanzer, UniSoft Systems, Berkeley
- X unisoft!jef@ucbvax.Berkeley.Edu
- X ...ucbvax!unisoft!jef
- X (415)644-1230
- X
- X
- X* Unix is a virus from outer space.
- X
- X
- X .--
- X .--
- X .-'
- X .-'@
- X /@@@
- X ./
- X /@@ o
- X /@@@@
- X |@@@@@
- X /@@@@@ Last Quarter +
- X | @@@@ 4 1:36:10
- X |@ @@@ New Moon -
- X | 3 7:34:53
- X \ . @
- X |
- X \ @
- X \ o
- X `\
- X \
- X `-.
- X `-.
- X `--
- X `--
- SHAR_EOF
- if test 2571 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 2571 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Makefile'" '(2137 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X# Makefile for phoon, deltime, parsetime, and libtws (stolen from mh).
- X
- X
- X# Valid options:
- X# BSD42 Set this if your system is BSD 4.2 or later.
- X# SYS5 Set this if your system is System V.
- X# EUROPE Makes nn/nn/nn mean dd/mm/yy instead of mm/dd/yy.
- X# ATZ This has something to do with alpha-numeric time zones.
- X# DSTXXX This has something to do with daylight savings time.
- X# HUJI I don't
- X# INETONLY know what
- X# LEXDEBUG the rest of these
- X# ONECASE do.
- XOPTIONS = -DBSD42 -DATZ -DDSTXXX -DONECASE
- X
- X
- XCC = cc
- XCFLAGS = -O $(OPTIONS)
- XLDFLAGS = -ns
- X
- X.SUFFIXES: .man .cat
- X.man.cat:
- X nroff -h -man $< > $@
- X
- X
- Xall: phoon phoon.cat deltime deltime.cat libtws.cat
- X
- X
- Xphoon: phoon.o libtws.a
- X $(CC) $(LDFLAGS) -o phoon phoon.o -lm libtws.a
- X
- Xphoon.o: phoon.c tws.h
- X
- X
- Xdeltime: deltime.o libtws.a
- X $(CC) $(LDFLAGS) -o deltime deltime.o libtws.a
- X
- Xdeltime.o: deltime.c tws.h
- X
- X
- Xparsetime: parsetime.o libtws.a
- X $(CC) $(LDFLAGS) -o parsetime parsetime.o libtws.a
- X
- Xparsetime.o: parsetime.c tws.h
- X
- X
- Xlibtws.a: dtime.o dtimep.o lexstring.o
- X ar r libtws.a dtime.o dtimep.o lexstring.o
- X# The following amusing bullshit makes sure that ranlib
- X# gets executed if it is present, no matter which shell
- X# make uses. If there's a better way to do this, someone
- X# please tell me!
- X -if test -r /usr/bin/ranlib ; then ranlib libtws.a ; fi
- X -if ( -r /usr/bin/ranlib ) ranlib libtws.a
- X
- X
- Xdtime.o: dtime.c tws.h
- X
- X
- Xdtimep.o: dtimep.c tws.h
- X
- Xdtimep.c: dtimep.lex
- X lex -nt dtimep.lex | sed -f lexedit.sed > dtimep.c
- X
- X
- Xlexstring.o: lexstring.c
- X $(CC) $(CFLAGS) -c lexstring.c
- X
- X
- Xclean:
- X -rm -f dtimep.c *.o libtws.a phoon deltime parsetime *.cat phoon.shar* core
- X
- Xphoon.shar: phoon.shar1 phoon.shar2
- X
- Xphoon.shar1: README Makefile deltime.c deltime.man dtime.c dtimep.lex
- X shar -v -c -p X README Makefile deltime.c deltime.man dtime.c dtimep.lex > phoon.shar1
- X
- Xphoon.shar2: lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h
- X shar -v -c -p X lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h > phoon.shar2
- SHAR_EOF
- if test 2137 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 2137 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'deltime.c'" '(2156 characters)'
- if test -f 'deltime.c'
- then
- echo shar: will not over-write existing file "'deltime.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'deltime.c'
- X/* deltime.c - subtract date/times
- X
- Xver date who remarks
- X--- ------- --- -------------------------------------------------------------
- X01B 15nov86 JP Modified to use twsubtract().
- X01A 08nov86 JP Written.
- X
- XCopyright (C) 1986 by Jef Poskanzer. Permission to use, copy,
- Xmodify, and distribute this software and its documentation for any
- Xpurpose and without fee is hereby granted, provided that this copyright
- Xnotice appear in all copies and in all supporting documentation. No
- Xrepresentation is made about the suitability of this software for any
- Xpurpose. It is provided "as is" without express or implied warranty.
- X
- X*/
- X
- Xstatic char copyright[] = "\nCopyright (C) 1986 by Jef Poskanzer.\n";
- X
- X
- X#include "tws.h"
- X#include <stdio.h>
- X
- X#define SECSPERMINUTE 60
- X#define SECSPERHOUR (60 * SECSPERMINUTE)
- X#define SECSPERDAY (24 * SECSPERHOUR)
- X
- Xmain( argc, argv )
- Xint argc;
- Xchar *argv[];
- X {
- X struct tws tws1, tws2, *twp;
- X long delta, days, hours, minutes, secs;
- X char *illdt = "illegal date/time: %s\n";
- X
- X if ( argc == 2 )
- X {
- X twp = dparsetime( argv[1] );
- X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
- X {
- X fprintf( stderr, illdt, argv[1] );
- X exit( 1 );
- X }
- X twscopy( &tws1, twp );
- X twscopy( &tws2, dtwstime( ) );
- X }
- X else if ( argc == 3 )
- X {
- X twp = dparsetime( argv[1] );
- X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
- X {
- X fprintf( stderr, illdt, argv[1] );
- X exit( 1 );
- X }
- X twscopy( &tws1, twp );
- X twp = dparsetime( argv[2] );
- X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
- X {
- X fprintf( stderr, illdt, argv[2] );
- X exit( 1 );
- X }
- X twscopy( &tws2, twp );
- X }
- X else
- X {
- X fprintf( stderr, "usage: %s <time> [ <time2> ]\n", argv[0] );
- X exit( 1 );
- X }
- X
- X delta = twsubtract( &tws2, &tws1 );
- X if ( delta < 0 )
- X {
- X printf( "-" );
- X delta = -delta;
- X }
- X
- X days = delta / SECSPERDAY;
- X delta = delta - days * SECSPERDAY;
- X hours = delta / SECSPERHOUR;
- X delta = delta - hours * SECSPERHOUR;
- X minutes = delta / SECSPERMINUTE;
- X delta = delta - minutes * SECSPERMINUTE;
- X secs = delta;
- X
- X printf( "%ld %2ld:%02ld:%02ld\n", days, hours, minutes, secs );
- X
- X exit( 0 );
- X }
- SHAR_EOF
- if test 2156 -ne "`wc -c < 'deltime.c'`"
- then
- echo shar: error transmitting "'deltime.c'" '(should have been 2156 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'deltime.man'" '(803 characters)'
- if test -f 'deltime.man'
- then
- echo shar: will not over-write existing file "'deltime.man'"
- else
- sed 's/^X//' << \SHAR_EOF > 'deltime.man'
- X.TH example 1 "08 November 1986"
- X.SH NAME
- Xdeltime \- compute a delta time
- X.SH SYNOPSIS
- X.in +.5i
- X.ti -.5i
- Xdeltime <time> \%[ <time2> ]
- X.in -.5i
- X.SH DESCRIPTION
- X.PP
- X.I Deltime
- Xcomputes the elapsed time between now and a
- Xspecified date/time, or between two specified date/times.
- XThe format for specifying date/times is pretty loose - basically
- Xthe same as the format for date/times in network mail.
- XJust be careful to put them in quotes if they contain spaces.
- XThe output format is dddd hh:mm:ss.
- X.PP
- XTimes earlier than 1970
- X.I can
- Xbe handled, because the internal Unix* time format is not used.
- XHowever, time spans greater than 66 years
- X.I cannot
- Xbe handled, because that's 2**31 seconds.
- X.SH "SEE\ ALSO"
- X.IR phoon(1),
- X.IR libtws(3)
- X.SH AUTHOR
- XJef Poskanzer
- X.SH NOTE
- X* Unix is a virus from outer space.
- SHAR_EOF
- if test 803 -ne "`wc -c < 'deltime.man'`"
- then
- echo shar: error transmitting "'deltime.man'" '(should have been 803 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'dtime.c'" '(9035 characters)'
- if test -f 'dtime.c'
- then
- echo shar: will not over-write existing file "'dtime.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'dtime.c'
- X/* dtime.c - routines to do ``ARPA-style'' time structures
- X
- Xver date who remarks
- X--- ------- --- -------------------------------------------------------------
- X01B 15nov86 JP Thouroughly hacked by Jef Poskanzer.
- X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
- X of Marshall Rose.
- X
- X*/
- X
- X
- X#include "tws.h"
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <time.h>
- X#ifdef SYS5
- X#include <string.h>
- X#else SYS5
- X#include <strings.h>
- X#include <sys/timeb.h>
- X#endif SYS5
- X
- X#ifdef SYS5
- Xextern int daylight;
- Xextern long timezone;
- Xextern char *tzname[];
- X#endif SYS5
- X
- X/* */
- X
- X#define abs(a) ( a >= 0 ? a : -a )
- X
- Xchar *tw_moty[] = {
- X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
- X
- Xchar *tw_dotw[] = {
- X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
- X
- Xchar *tw_ldotw[] = {
- X "Sunday", "Monday", "Tuesday", "Wednesday",
- X "Thursday", "Friday", "Saturday", NULL };
- X
- X/* */
- X
- Xstatic struct zone
- X {
- X char *std;
- X char *dst;
- X int shift;
- X }
- X zones[] = {
- X "GMT", "BST", 0,
- X "EST", "EDT", -5,
- X "CST", "CDT", -6,
- X "MST", NULL, -7,
- X "PST", "PDT", -8,
- X "A", NULL, -1,
- X "B", NULL, -2,
- X "C", NULL, -3,
- X "D", NULL, -4,
- X "E", NULL, -5,
- X "F", NULL, -6,
- X "G", NULL, -7,
- X "H", NULL, -8,
- X "I", NULL, -9,
- X "K", NULL, -10,
- X "L", NULL, -11,
- X "M", NULL, -12,
- X "N", NULL, 1,
- X#ifndef HUJI
- X "O", NULL, 2,
- X#else HUJI
- X "JST", "JDT", 2,
- X#endif HUJI
- X "P", NULL, 3,
- X "Q", NULL, 4,
- X "R", NULL, 5,
- X "S", NULL, 6,
- X "T", NULL, 7,
- X "U", NULL, 8,
- X "V", NULL, 9,
- X "W", NULL, 10,
- X "X", NULL, 11,
- X "Y", NULL, 12,
- X NULL };
- X
- X#define CENTURY 19
- X
- Xlong time( );
- Xstruct tm *localtime( );
- X
- X/* */
- X
- Xchar *dtimenow( )
- X {
- X long clock;
- X
- X (void) time( &clock );
- X return ( dtime( &clock ) );
- X }
- X
- X
- Xchar *
- Xdctime( tw )
- Xstruct tws *tw;
- X {
- X static char buffer[25];
- X
- X if ( tw == NULL )
- X return ( NULL );
- X
- X (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
- X tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday,
- X tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
- X tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year );
- X
- X return ( buffer );
- X }
- X
- X/* */
- X
- Xstruct tws *
- Xdtwstime( )
- X {
- X long clock;
- X
- X (void) time( &clock );
- X return ( dlocaltime( &clock ) );
- X }
- X
- X
- Xstruct tws *
- Xdlocaltime( clock )
- Xlong *clock;
- X {
- X register struct tm *tm;
- X#ifndef SYS5
- X struct timeb tb;
- X#endif not SYS5
- X static struct tws tw;
- X
- X if ( clock == NULL )
- X return ( NULL );
- X tw.tw_flags = TW_NULL;
- X
- X tm = localtime( clock );
- X tw.tw_sec = tm -> tm_sec;
- X tw.tw_min = tm -> tm_min;
- X tw.tw_hour = tm -> tm_hour;
- X tw.tw_mday = tm -> tm_mday;
- X tw.tw_mon = tm -> tm_mon;
- X tw.tw_year = tm -> tm_year;
- X tw.tw_wday = tm -> tm_wday;
- X tw.tw_yday = tm -> tm_yday;
- X if ( tm -> tm_isdst )
- X tw.tw_flags |= TW_DST;
- X#ifndef SYS5
- X ftime( &tb );
- X tw.tw_zone = -tb.timezone;
- X#else SYS5
- X tzset( );
- X tw.tw_zone = -(timezone / 60);
- X#endif SYS5
- X tw.tw_flags &= ~TW_SDAY;
- X tw.tw_flags |= TW_SEXP;
- X tw.tw_clock = *clock;
- X
- X return ( &tw );
- X }
- X
- X
- Xstruct tws *
- Xdgmtime( clock )
- Xlong *clock;
- X {
- X register struct tm *tm;
- X static struct tws tw;
- X
- X if ( clock == NULL )
- X return ( NULL );
- X tw.tw_flags = TW_NULL;
- X
- X tm = gmtime( clock );
- X tw.tw_sec = tm -> tm_sec;
- X tw.tw_min = tm -> tm_min;
- X tw.tw_hour = tm -> tm_hour;
- X tw.tw_mday = tm -> tm_mday;
- X tw.tw_mon = tm -> tm_mon;
- X tw.tw_year = tm -> tm_year;
- X tw.tw_wday = tm -> tm_wday;
- X tw.tw_yday = tm -> tm_yday;
- X if ( tm -> tm_isdst )
- X tw.tw_flags |= TW_DST;
- X tw.tw_zone = 0;
- X tw.tw_flags &= ~TW_SDAY;
- X tw.tw_flags |= TW_SEXP;
- X tw.tw_clock = *clock;
- X
- X return( &tw );
- X }
- X
- X/* */
- X
- Xchar *
- Xdasctime( tw, flags )
- Xstruct tws *tw;
- Xint flags;
- X {
- X static char buffer[80], result[80];
- X
- X if ( tw == NULL )
- X return ( NULL );
- X
- X (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s",
- X tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year,
- X tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
- X dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) );
- X
- X if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP )
- X (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer );
- X else
- X if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL )
- X (void) strcpy( result, buffer );
- X else
- X (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] );
- X
- X return ( result );
- X }
- X
- X/* */
- X
- Xchar *
- Xdtimezone( offset, flags )
- Xint offset, flags;
- X {
- X register int hours, mins;
- X register struct zone *z;
- X static char buffer[10];
- X
- X if ( offset < 0 )
- X {
- X mins = -((-offset) % 60);
- X hours = -((-offset) / 60);
- X }
- X else
- X {
- X mins = offset % 60;
- X hours = offset / 60;
- X }
- X
- X if ( !(flags & TW_ZONE) && mins == 0 )
- X for ( z = zones; z -> std; z++ )
- X if ( z -> shift == hours )
- X return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std );
- X
- X#ifdef DSTXXX
- X if ( flags & TW_DST )
- X hours += 1;
- X#endif DSTXXX
- X (void) sprintf( buffer, "%s%02d%02d",
- X offset < 0 ? "-" : "+", abs( hours ), abs( mins ) );
- X return ( buffer );
- X }
- X
- X/* */
- X
- Xvoid
- Xtwscopy( tb, tw )
- Xstruct tws *tb, *tw;
- X {
- X#ifdef notdef
- X tb -> tw_sec = tw -> tw_sec;
- X tb -> tw_min = tw -> tw_min;
- X tb -> tw_hour = tw -> tw_hour;
- X tb -> tw_mday = tw -> tw_mday;
- X tb -> tw_mon = tw -> tw_mon;
- X tb -> tw_year = tw -> tw_year;
- X tb -> tw_wday = tw -> tw_wday;
- X tb -> tw_yday = tw -> tw_yday;
- X tb -> tw_zone = tw -> tw_zone;
- X tb -> tw_clock = tw -> tw_clock;
- X tb -> tw_flags = tw -> tw_flags;
- X#else not notdef
- X *tb = *tw;
- X#endif not notdef
- X }
- X
- X
- Xint
- Xtwsort( tw1, tw2 )
- Xstruct tws *tw1, *tw2;
- X {
- X register long c1, c2;
- X
- X (void) twclock( tw1 );
- X (void) twclock( tw2 );
- X
- X return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
- X : c1 == c2 ? 0 : -1 );
- X }
- X
- X/* */
- X
- X
- X/* Julian day number of the Unix* clock's origin, 01 Jan 1970. */
- X#define JD1970 2440587L
- X
- X
- Xlong
- Xtwjuliandate( tw )
- Xstruct tws *tw;
- X {
- X register int mday, mon, year;
- X register long a, b;
- X double jd;
- X
- X if ( (mday = tw -> tw_mday) < 1 || mday > 31 ||
- X (mon = tw -> tw_mon + 1) < 1 || mon > 12 ||
- X (year = tw -> tw_year) < 1 || year > 10000 )
- X return ( -1L );
- X if ( year < 100 )
- X year += CENTURY * 100;
- X
- X if ( mon == 1 || mon == 2 )
- X {
- X --year;
- X mon += 12;
- X }
- X if ( year < 1583 )
- X return ( -1L );
- X a = year / 100;
- X b = 2 - a + a / 4;
- X b += (long) ( (double) year * 365.25 );
- X b += (long) ( 30.6001 * ( (double) mon + 1.0 ) );
- X jd = mday + b + 1720994.5;
- X return ( (long) jd );
- X }
- X
- X
- Xlong
- Xtwsubdayclock( tw )
- Xstruct tws *tw;
- X {
- X register int i, sec, min, hour;
- X register long result;
- X
- X if ( (sec = tw -> tw_sec) < 0 || sec > 59 ||
- X (min = tw -> tw_min) < 0 || min > 59 ||
- X (hour = tw -> tw_hour) < 0 || hour > 23 )
- X return ( -1L );
- X
- X result = ( hour * 60 + min ) * 60 + sec;
- X result -= 60 * tw -> tw_zone;
- X if ( tw -> tw_flags & TW_DST )
- X result -= 60 * 60;
- X
- X return ( result );
- X }
- X
- X
- Xlong
- Xtwclock( tw )
- Xstruct tws *tw;
- X {
- X register long jd, sdc, result;
- X
- X if ( tw -> tw_clock != 0L )
- X return ( tw -> tw_clock );
- X
- X if ( ( jd = twjuliandate( tw ) ) == -1L )
- X return ( tw -> tw_clock = -1L );
- X if ( ( sdc = twsubdayclock( tw ) ) == -1L )
- X return ( tw -> tw_clock = -1L );
- X
- X result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
- X
- X return ( tw -> tw_clock = result );
- X }
- X
- X/* */
- X
- X/*** twsubtract - subtract tw2 from tw1, returning result in seconds
- X
- XThe point of this routine is that using twclock( tw1 ) - twclock( tw2 )
- Xwould limit you to dates after the Unix* Epoch ( 01 January 1970 ). This
- Xroutine avoids that limit. However, because the result is represented
- Xby 32 bits, it is still limited to a span of two billion seconds, which is
- Xabout 66 years.
- X
- X*/
- X
- Xlong
- Xtwsubtract( tw1, tw2 )
- Xstruct tws *tw1, *tw2;
- X {
- X register long jd1, jd2, sdc1, sdc2, result;
- X
- X if ( ( jd1 = twjuliandate( tw1 ) ) == -1L )
- X return ( 0L );
- X if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L )
- X return ( 0L );
- X
- X if ( ( jd2 = twjuliandate( tw2 ) ) == -1L )
- X return ( 0L );
- X if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L )
- X return ( 0L );
- X
- X result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 );
- X
- X return ( result );
- X }
- X
- X/* */
- X
- X/*
- X * Simple calculation of day of the week. Algorithm used is Zeller's
- X * congruence. Currently, we assume if tw -> tw_year < 100
- X * then the century is CENTURY.
- X */
- X
- Xset_dotw( tw )
- Xstruct tws *tw;
- X {
- X register int month, day, year, century;
- X
- X month = tw -> tw_mon - 1;
- X day = tw -> tw_mday;
- X year = tw -> tw_year % 100;
- X century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY;
- X
- X if ( month <= 0 )
- X {
- X month += 12;
- X if ( --year < 0 )
- X {
- X year += 100;
- X century--;
- X }
- X }
- X
- X tw -> tw_wday =
- X ((26 * month - 2) / 10 + day + year + year / 4
- X - 3 * century / 4 + 1) % 7;
- X
- X tw -> tw_flags &= ~TW_SDAY;
- X tw -> tw_flags |= TW_SIMP;
- X }
- X
- X
- X/* * Unix is a virus from outer space. */
- SHAR_EOF
- if test 9035 -ne "`wc -c < 'dtime.c'`"
- then
- echo shar: error transmitting "'dtime.c'" '(should have been 9035 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'dtimep.lex'" '(7327 characters)'
- if test -f 'dtimep.lex'
- then
- echo shar: will not over-write existing file "'dtimep.lex'"
- else
- sed 's/^X//' << \SHAR_EOF > 'dtimep.lex'
- X%e 2000
- X%p 5000
- X%n 1000
- X%a 4000
- X%START Z
- Xsun (sun(day)?)
- Xmon (mon(day)?)
- Xtue (tue(sday)?)
- Xwed (wed(nesday)?)
- Xthu (thu(rsday)?)
- Xfri (fri(day)?)
- Xsat (sat(urday)?)
- X
- XDAY ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
- X
- Xjan (jan(uary)?)
- Xfeb (feb(ruary)?)
- Xmar (mar(ch)?)
- Xapr (apr(il)?)
- Xmay (may)
- Xjun (jun(e)?)
- Xjul (jul(y)?)
- Xaug (aug(ust)?)
- Xsep (sep(tember)?)
- Xoct (oct(ober)?)
- Xnov (nov(ember)?)
- Xdec (dec(ember)?)
- X
- XMONTH ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
- X
- Xw ([ \t]*)
- XW ([ \t]+)
- XD ([0-9]?[0-9])
- Xd [0-9]
- X%{
- X/* dtimep.lex - routines to do ``ARPA-style'' time parsing
- X
- Xver date who remarks
- X--- ------- --- -------------------------------------------------------------
- X01B 15nov86 JP Thouroughly hacked by Jef Poskanzer.
- X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
- X of Marshall Rose.
- X
- X*/
- X
- X#include "tws.h"
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <time.h>
- X#ifdef SYS5
- X#include <string.h>
- X#else SYS5
- X#include <strings.h>
- X#include <sys/timeb.h>
- X#endif SYS5
- X
- X#ifdef SYS5
- Xextern int daylight;
- Xextern long timezone;
- Xextern char *tzname[];
- X#endif SYS5
- X
- X/*
- X * Table to convert month names to numeric month. We use the
- X * fact that the low order 5 bits of the sum of the 2nd & 3rd
- X * characters of the name is a hash with no collisions for the 12
- X * valid month names. (The mask to 5 bits maps any combination of
- X * upper and lower case into the same hash value).
- X */
- Xstatic int month_map[] = {
- X 0,
- X 6, /* 1 - Jul */
- X 3, /* 2 - Apr */
- X 5, /* 3 - Jun */
- X 0,
- X 10, /* 5 - Nov */
- X 0,
- X 1, /* 7 - Feb */
- X 11, /* 8 - Dec */
- X 0,
- X 0,
- X 0,
- X 0,
- X 0,
- X 0,
- X 0, /*15 - Jan */
- X 0,
- X 0,
- X 0,
- X 2, /*19 - Mar */
- X 0,
- X 8, /*21 - Sep */
- X 0,
- X 9, /*23 - Oct */
- X 0,
- X 0,
- X 4, /*26 - May */
- X 0,
- X 7 }; /*28 - Aug */
- X/*
- X * Same trick for day-of-week using the hash function
- X * (c1 & 7) + (c2 & 4)
- X */
- Xstatic int day_map[] = {
- X 0,
- X 0,
- X 0,
- X 6, /* 3 - Sat */
- X 4, /* 4 - Thu */
- X 0,
- X 5, /* 6 - Fri */
- X 0, /* 7 - Sun */
- X 2, /* 8 - Tue */
- X 1 /* 9 - Mon */,
- X 0,
- X 3 }; /*11 - Wed */
- X#define SETDAY tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
- X tw.tw_flags |= TW_SEXP;\
- X cp += 2;
- X#define SETMONTH tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; gotdate++;\
- X cp += 2;\
- X SKIPD;
- X#define CVT1OR2 (i=(*cp++ - '0'), isdigit(*cp)? i*10 + (*cp++ - '0') : i)
- X#define CVT2 ( (*cp++ - '0')*10 + (*cp++ - '0') )
- X#define CVT3 ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
- X#define CVT4 ( ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
- X#define SKIPD while ( ! isdigit( *cp++ ) ) ; --cp;
- X#define ZONE(x) tw.tw_zone=(x);
- X#define ZONED(x) tw.tw_zone=(x); tw.tw_flags |= TW_DST;
- X#define LC(c) (isupper( c ) ? tolower( c ) : ( c ))
- X%}
- X%%
- X%{
- Xstruct tws *
- Xdparsetime( str )
- Xchar *str;
- X {
- X register int i;
- X static struct tws tw;
- X register char *cp;
- X register int gotdate = 0;
- X#ifndef SYS5
- X struct timeb tb;
- X#endif not SYS5
- X long clock;
- X
- X start_cond = 0;
- X
- X /* Zero out the struct. */
- X bzero( (char *) &tw, sizeof tw );
- X
- X /* Set default time zone. */
- X#ifndef SYS5
- X ftime( &tb );
- X tw.tw_zone = -tb.timezone;
- X#else SYS5
- X tzset( );
- X tw.tw_zone = -(timezone / 60);
- X#endif SYS5
- X
- X for ( ; ; )
- X switch ( cp = str, lex_string( &str, start_cond ) )
- X {
- X case -1:
- X if ( ! gotdate )
- X return ( NULL );
- X tw.tw_flags |= TW_JUNK;
- X /* fall through */
- X case 0:
- X if ( tw.tw_year == 0 )
- X {
- X /* Set default year. */
- X time( &clock );
- X tw.tw_year = localtime( &clock ) -> tm_year;
- X }
- X return ( &tw );
- X
- X%}
- X{DAY}","?{w} SETDAY;
- X"("{DAY}")"(","?) cp++, SETDAY;
- X
- X{D}(("-"{D}"-")|("/"{D}"/")){D}?{d}{d}{w} {
- X#ifdef EUROPE
- X tw.tw_mday = CVT1OR2; cp++;
- X tw.tw_mon = CVT1OR2 - 1; cp++;
- X#else EUROPE
- X tw.tw_mon = CVT1OR2 - 1; cp++;
- X tw.tw_mday = CVT1OR2; cp++;
- X#endif EUROPE
- X for ( i = 0; isdigit( *cp ); )
- X i = i * 10 + (*cp++ - '0');
- X tw.tw_year = i;
- X gotdate++;
- X }
- X{D}("/"|"-"){D}{w} {
- X#ifdef EUROPE
- X tw.tw_mday = CVT1OR2; cp++;
- X tw.tw_mon = CVT1OR2 - 1;
- X#else EUROPE
- X tw.tw_mon = CVT1OR2 - 1; cp++;
- X tw.tw_mday = CVT1OR2;
- X#endif EUROPE
- X gotdate++;
- X }
- X{D}(("-"{MONTH}"-")|(" "{MONTH}" ")|({MONTH})){D}?{d}{d}({W}at)?{w} {
- X tw.tw_mday = CVT1OR2;
- X while ( ! isalpha( *cp++ ) )
- X ;
- X SETMONTH;
- X for ( i = 0; isdigit( *cp ); )
- X i = i * 10 + (*cp++ - '0');
- X tw.tw_year = i;
- X gotdate++;
- X }
- X{D}"-"?{MONTH}({W}at)?{w} {
- X tw.tw_mday = CVT1OR2;
- X while ( ! isalpha( *cp++ ) )
- X ;
- X SETMONTH;
- X gotdate++;
- X }
- X{MONTH}{W}{D}","{W}{D}?{d}{d}{w} {
- X cp++;
- X SETMONTH;
- X tw.tw_mday = CVT1OR2;
- X SKIPD;
- X for ( i = 0; isdigit( *cp ); )
- X i = i * 10 + (*cp++ - '0');
- X tw.tw_year = i;
- X gotdate++;
- X }
- X{MONTH}{W}{D}{w} {
- X cp++;
- X SETMONTH;
- X tw.tw_mday = CVT1OR2;
- X gotdate++;
- X }
- X
- X{D}:{D}:{D}({w}am)?{w} {
- X tw.tw_hour = CVT1OR2; cp++;
- X tw.tw_min = CVT1OR2; cp++;
- X tw.tw_sec = CVT1OR2;
- X BEGIN Z;
- X }
- X{D}:{D}:{D}{w}pm{w} {
- X tw.tw_hour = CVT1OR2 + 12; cp++;
- X tw.tw_min = CVT1OR2; cp++;
- X tw.tw_sec = CVT1OR2;
- X BEGIN Z;
- X }
- X{D}:{D}({w}am)?{w} {
- X tw.tw_hour = CVT1OR2; cp++;
- X tw.tw_min = CVT1OR2;
- X BEGIN Z;
- X }
- X{D}:{D}{w}pm{w} {
- X tw.tw_hour = CVT1OR2 + 12; cp++;
- X tw.tw_min = CVT1OR2;
- X BEGIN Z;
- X }
- X[0-2]{d}{d}{d}{d}{d}{w} {
- X tw.tw_hour = CVT1OR2;
- X tw.tw_min = CVT1OR2;
- X tw.tw_sec = CVT1OR2;
- X BEGIN Z;
- X }
- X[0-2]{d}{d}{d}{w} {
- X tw.tw_hour = CVT1OR2;
- X tw.tw_min = CVT1OR2;
- X BEGIN Z;
- X }
- X<Z>"-"?ut ZONE(0 * 60);
- X<Z>"-"?gmt ZONE(0 * 60);
- X<Z>"-"?jst ZONE(2 * 60);
- X<Z>"-"?jdt ZONED(2 * 60);
- X<Z>"-"?est ZONE(-5 * 60);
- X<Z>"-"?edt ZONED(-5 * 60);
- X<Z>"-"?cst ZONE(-6 * 60);
- X<Z>"-"?cdt ZONED(-6 * 60);
- X<Z>"-"?mst ZONE(-7 * 60);
- X<Z>"-"?mdt ZONED(-7 * 60);
- X<Z>"-"?pst ZONE(-8 * 60);
- X<Z>"-"?pdt ZONED(-8 * 60);
- X<Z>"-"?nst ZONE(-(3 * 60 + 30));
- X<Z>"-"?ast ZONE(-4 * 60);
- X<Z>"-"?adt ZONED(-4 * 60);
- X<Z>"-"?yst ZONE(-9 * 60);
- X<Z>"-"?ydt ZONED(-9 * 60);
- X<Z>"-"?hst ZONE(-10 * 60);
- X<Z>"-"?hdt ZONED(-10 * 60);
- X<Z>"-"?bst ZONED(-1 * 60);
- X<Z>[a-i] tw.tw_zone = 60 * (('a'-1) - LC (*cp));
- X<Z>[k-m] tw.tw_zone = 60 * ('a' - LC (*cp));
- X<Z>[n-y] tw.tw_zone = 60 * (LC (*cp) - 'm');
- X<Z>"+"[0-1]{d}{d}{d} {
- X cp++;
- X tw.tw_zone = ((cp[0] * 10 + cp[1])
- X -('0' * 10 + '0'))*60
- X +((cp[2] * 10 + cp[3])
- X -('0' * 10 + '0'));
- X#ifdef DSTXXX
- X zonehack (&tw);
- X#endif DSTXXX
- X cp += 4;
- X }
- X<Z>"-"[0-1]{d}{d}{d} {
- X cp++;
- X tw.tw_zone = (('0' * 10 + '0')
- X -(cp[0] * 10 + cp[1]))*60
- X +(('0' * 10 + '0')
- X -(cp[2] * 10 + cp[3]));
- X#ifdef DSTXXX
- X zonehack (&tw);
- X#endif DSTXXX
- X cp += 4;
- X }
- X
- X<Z>{W}{d}{d}{d}{d} {
- X SKIPD;
- X tw.tw_year = CVT4;
- X }
- X\n |
- X{W} ;
- X%%
- X
- X#ifdef DSTXXX
- Xstatic
- Xzonehack( tw )
- Xregister struct tws *tw;
- X {
- X register struct tm *tm;
- X
- X if ( twclock( tw ) == -1L )
- X return;
- X
- X tm = localtime( &tw -> tw_clock );
- X if ( tm -> tm_isdst )
- X {
- X tw -> tw_flags |= TW_DST;
- X tw -> tw_zone -= 60;
- X }
- X }
- X#endif DSTXXX
- X
- X
- X#ifdef SYS5
- X/* Not all SYS5's have bzero( ). */
- X
- Xbzero( b, length )
- Xchar *b;
- Xint length;
- X {
- X while ( length-- > 0 )
- X *b++ = 0;
- X }
- X#endif
- SHAR_EOF
- if test 7327 -ne "`wc -c < 'dtimep.lex'`"
- then
- echo shar: error transmitting "'dtimep.lex'" '(should have been 7327 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'lexedit.sed'" '(356 characters)'
- if test -f 'lexedit.sed'
- then
- echo shar: will not over-write existing file "'lexedit.sed'"
- else
- sed 's/^X//' << \SHAR_EOF > 'lexedit.sed'
- X2,/^extern int yylineno;$/c\
- Xstatic int start_cond = 0;\
- X#define BEGIN start_cond =
- X/^struct yysvf \*yyestate;$/,/^extern struct yysvf yysvec/d
- X/^# define YYNEWLINE /,/^int nstr;/d
- X/^while((nstr = yylook()/,/^if(yywrap()) /d
- X/^case -1:$/,/^fprintf(yyout,"bad switch yylook /c\
- X default: return(0);
- X/^struct yysvf *yybgin = yysvec+1;$/d
- X/^int yylineno /,$d
- SHAR_EOF
- if test 356 -ne "`wc -c < 'lexedit.sed'`"
- then
- echo shar: error transmitting "'lexedit.sed'" '(should have been 356 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'lexstring.c'" '(3765 characters)'
- if test -f 'lexstring.c'
- then
- echo shar: will not over-write existing file "'lexstring.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'lexstring.c'
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#define YYLERR yysvec
- X#define YYTYPE int
- X#define YYLMAX 256
- X
- Xstruct yysvf {
- X struct yywork *yystoff;
- X struct yysvf *yyother;
- X int *yystops;
- X};
- X
- Xstruct yywork {
- X YYTYPE verify;
- X YYTYPE advance;
- X};
- X
- Xextern int yyvstop[];
- Xextern struct yywork yycrank[];
- Xextern struct yysvf yysvec[];
- Xextern struct yywork *yytop;
- Xextern char yymatch[];
- Xextern char yyextra[];
- X
- X#ifdef LEXDEBUG
- Xstatic int debug = 0;
- X#endif LEXDEBUG
- X
- Xlex_string( strptr, start_cond)
- X char **strptr;
- X int start_cond;
- X{
- X register struct yysvf *state, **lsp;
- X register struct yywork *tran;
- X register int ch;
- X register char *cp = *strptr;
- X register int *found;
- X struct yysvf *yylstate[YYLMAX];
- X
- X /* start off machines */
- X lsp = yylstate;
- X state = yysvec+1+start_cond;
- X for (;;){
- X# ifdef LEXDEBUG
- X if(debug)
- X fprintf(stderr,"state %d\n",state-yysvec-1);
- X# endif
- X tran = state->yystoff;
- X if(tran == yycrank)
- X /* may not be any transitions */
- X if (state->yyother == 0 ||
- X state->yyother->yystoff == yycrank)
- X break;
- X
- X ch = *cp++;
- X#ifdef ONECASE
- X if (isupper(ch) )
- X ch = tolower(ch);
- X#endif ONECASE
- Xtryagain:
- X# ifdef LEXDEBUG
- X if(debug){
- X fprintf(stderr,"char ");
- X allprint(ch);
- X putchar('\n');
- X }
- X# endif
- X if ( tran > yycrank){
- X tran += ch;
- X if (tran <= yytop && tran->verify+yysvec == state){
- X if ((state = tran->advance+yysvec) == YYLERR){
- X /* error transitions */
- X --cp;
- X break;
- X }
- X *lsp++ = state;
- X goto contin;
- X }
- X
- X } else if(tran < yycrank) {
- X /* r < yycrank */
- X tran = yycrank+(yycrank-tran) + ch;
- X# ifdef LEXDEBUG
- X if (debug)
- X fprintf(stderr,"compressed state\n");
- X# endif
- X if(tran <= yytop && tran->verify+yysvec == state){
- X if ((state = tran->advance+yysvec) == YYLERR)
- X /* error transitions */
- X break;
- X
- X *lsp++ = state;
- X goto contin;
- X }
- X tran += (yymatch[ch] - ch);
- X# ifdef LEXDEBUG
- X if(debug){
- X fprintf(stderr,"try fall back character ");
- X allprint(yymatch[ch]);
- X putchar('\n');
- X }
- X# endif
- X if(tran <= yytop && tran->verify+yysvec == state){
- X if(tran->advance+yysvec == YYLERR)
- X /* error transition */
- X break;
- X
- X *lsp++ = state = tran->advance+yysvec;
- X goto contin;
- X }
- X }
- X if ((state = state->yyother) &&
- X (tran = state->yystoff) != yycrank){
- X# ifdef LEXDEBUG
- X if(debug)
- X fprintf(stderr,"fall back to state %d\n",
- X state-yysvec-1);
- X# endif
- X goto tryagain;
- X } else
- X break;
- X
- Xcontin:
- X# ifdef LEXDEBUG
- X if(debug){
- X fprintf(stderr,"state %d char ",state-yysvec-1);
- X allprint(ch);
- X putchar('\n');
- X }
- X# endif
- X ;
- X }
- X# ifdef LEXDEBUG
- X if(debug){
- X fprintf(stderr,"stopped at %d with ",*(lsp-1)-yysvec-1);
- X allprint(ch);
- X putchar('\n');
- X }
- X# endif
- X while (lsp-- > yylstate){
- X if (*lsp != 0 && (found= (*lsp)->yystops) && *found > 0){
- X if(yyextra[*found]){
- X /* must backup */
- X ch = -*found;
- X do {
- X while (*found && *found++ != ch)
- X ;
- X } while (lsp > yylstate &&
- X (found = (*--lsp)->yystops));
- X }
- X# ifdef LEXDEBUG
- X if(debug){
- X fprintf(stderr,"\nmatch ");
- X for ( cp = *strptr;
- X cp <= ((*strptr)+(lsp-yylstate));
- X cp++)
- X allprint( *cp );
- X fprintf(stderr," action %d\n",*found);
- X }
- X# endif
- X *strptr += (lsp - yylstate + 1);
- X return(*found);
- X }
- X }
- X /* the string didn't match anything - if we're looking at
- X * eos, just return 0. Otherwise, bump the string pointer
- X * and return -1.
- X */
- X# ifdef LEXDEBUG
- X if(debug)
- X fprintf(stderr,"\nno match\n");
- X#endif LEXDEBUG
- X if ( **strptr ) {
- X (*strptr)++;
- X return (-1);
- X }
- X return (0);
- X}
- X
- X#ifdef LEXDEBUG
- Xallprint(c)
- X char c;
- X{
- X if ( c < 32 ) {
- X putc( '^', stderr );
- X c += 32;
- X } else if ( c == 127 ) {
- X putc( '^', stderr );
- X c = '?';
- X }
- X putc( c, stderr );
- X}
- X#endif LEXDEBUG
- SHAR_EOF
- if test 3765 -ne "`wc -c < 'lexstring.c'`"
- then
- echo shar: error transmitting "'lexstring.c'" '(should have been 3765 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'libtws.man'" '(2241 characters)'
- if test -f 'libtws.man'
- then
- echo shar: will not over-write existing file "'libtws.man'"
- else
- sed 's/^X//' << \SHAR_EOF > 'libtws.man'
- X.TH libtws 3 "08 November 1986"
- X.SH NAME
- Xlibtws \- alternate date and time routines including parsing
- X.SH SYNOPSIS
- X.nf
- X.fc ^ ~
- X.ta \w'char *dtimezone( offset, flags ); 'u
- Xinclude "tws.h"
- X.PP
- X^struct tws *dlocaltime( clock );~^/* local clock into tws */
- Xlong *clock;
- X.PP
- X^struct tws *gmtime( clock );~^/* GMT clock into tws */
- Xlong *clock;
- X.PP
- X^char *dtime( clock );~^/* clock into string */
- Xlong *clock;
- X.PP
- X^long twclock( t );~^/* tws into clock */
- Xstruct tws *t;
- X.PP
- X^long twjuliandate( t );~^/* tws into Julian day number */
- Xstruct tws *t;
- X.PP
- X^struct tws *dparsetime( str );~^/* string into tws */
- Xchar *str;
- X.PP
- X^char *dctime( t );~^/* tws into string */
- Xstruct tws *t;
- X.PP
- X^char *dasctime( t, flags );~^/* tws into string */
- Xstruct tws *t;
- Xint flags;
- X.PP
- X^char *dtimezone( offset, flags );~^/* timezone into string */
- Xint offset, flags;
- X.PP
- X^char *dtwszone( t );~^/* tws's timezone into string */
- Xstruct tws *t;
- X.PP
- X^char *dtimemow( );~^/* current time into string */
- X.PP
- X^struct tws *dtwstime( );~^/* current time into tws */
- X.PP
- X^void twscopy( tot, fromt );~^/* copy a tws */
- Xstruct tws *tot, *fromt;
- X.PP
- X^int twsort( t1, t2 );~^/* compare two tws's */
- Xstruct tws *t1, *t2;
- X.PP
- X^long twsubtract( t1, t2 );~^/* seconds between t2 and t1 */
- Xstruct tws *t1, *t2;
- X.fi
- X.SH DESCRIPTION
- X.I Libtws
- Xis a fairly complete date/time library.
- XUnlike the standard Unix* date/time routines,
- X.I libtws
- Xwill parse date/time strings into internal form.
- XThe format for specifying date/time strings is pretty loose - basically
- Xthe same as the format for date/times in network mail.
- X.PP
- XMost of the routines do not use the Unix* "clock" time
- Xformat, and therefore are not limited to dates after 01 January 1970.
- XIn particular, twsubtract() lets you subtract two dates without
- Xconverting them to "clock" form.
- X.SH "SEE\ ALSO"
- X.IR ctime(3),
- X.IR time(3)
- X.SH AUTHOR
- XMost of
- X.I libtws
- Xcame from version 6.5 of the MH message
- Xhandling system, courtesy of Marshall Rose.
- XSome improvements (?) were added by Jef Poskanzer.
- X.SH BUGS
- XThe return values point to static data whose contents are overwritten
- Xby the next call.
- X.PP
- XThe basic Unix* time format (clock) only goes back to 1970, limiting
- Xapplications somewhat.
- X.SH NOTE
- X* Unix is a virus from outer space.
- SHAR_EOF
- if test 2241 -ne "`wc -c < 'libtws.man'`"
- then
- echo shar: error transmitting "'libtws.man'" '(should have been 2241 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'parsetime.c'" '(1756 characters)'
- if test -f 'parsetime.c'
- then
- echo shar: will not over-write existing file "'parsetime.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'parsetime.c'
- X/* parsetime.c - parse a date/time and display the results
- X
- Xver date who remarks
- X--- ------- --- -------------------------------------------------------------
- X01A 15nov86 JP Written.
- X
- XCopyright (C) 1986 by Jef Poskanzer. Permission to use, copy,
- Xmodify, and distribute this software and its documentation for any
- Xpurpose and without fee is hereby granted, provided that this copyright
- Xnotice appear in all copies and in all supporting documentation. No
- Xrepresentation is made about the suitability of this software for any
- Xpurpose. It is provided "as is" without express or implied warranty.
- X
- X*/
- X
- Xstatic char copyright[] = "\nCopyright (C) 1986 by Jef Poskanzer.\n";
- X
- X
- X#include "tws.h"
- X#include <stdio.h>
- X
- X
- Xmain( argc, argv )
- Xint argc;
- Xchar *argv[];
- X {
- X char buf[200];
- X int i;
- X struct tws *twp;
- X
- X strcpy( buf, "" );
- X for ( i = 1; i < argc; i++ )
- X {
- X if ( i > 1 )
- X strcat( buf, " " );
- X strcat( buf, argv[i] );
- X }
- X
- X twp = dparsetime( buf );
- X if ( twp == NULL )
- X {
- X fprintf( stderr, "illegal date/time: %s\n", buf );
- X exit( 1 );
- X }
- X
- X printf( "dparsetime( \"%s\" ):\n", buf );
- X printf( " tw_sec = %d\n", twp->tw_sec );
- X printf( " tw_min = %d\n", twp->tw_min );
- X printf( " tw_hour = %d\n", twp->tw_hour );
- X printf( " tw_mday = %d\n", twp->tw_mday );
- X printf( " tw_mon = %d\n", twp->tw_mon );
- X printf( " tw_year = %d\n", twp->tw_year );
- X printf( " tw_wday = %d\n", twp->tw_wday );
- X printf( " tw_yday = %d\n", twp->tw_yday );
- X printf( " tw_zone = %d\n", twp->tw_zone );
- X printf( " tw_clock = %ld\n", twp->tw_clock );
- X printf( " tw_flags = %d (0x%04x)\n", twp->tw_flags, twp->tw_flags );
- X printf( "\n" );
- X printf( "dasctime: %s\n", dasctime( twp, 0 ) );
- X
- X exit( 0 );
- X }
- SHAR_EOF
- if test 1756 -ne "`wc -c < 'parsetime.c'`"
- then
- echo shar: error transmitting "'parsetime.c'" '(should have been 1756 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'phoon.c'" '(12899 characters)'
- if test -f 'phoon.c'
- then
- echo shar: will not over-write existing file "'phoon.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'phoon.c'
- X/* phoon - show the phase of the moon
- X
- Xver date who remarks
- X--- ------- --- -------------------------------------------------------------
- X01C 26jan87 JP Added backgrounds for 29 and 18 lines.
- X01B 28dec86 JP Added -l flag, and backgrounds for 19 and 24 lines.
- X01A 08nov86 JP Translated from the ratfor version of 12nov85, which itself
- X was translated from the Pascal version of 05apr79.
- X
- XCopyright (C) 1986 by Jeffrey A. Poskanzer. Permission to use, copy,
- Xmodify, and distribute this software and its documentation for any
- Xpurpose and without fee is hereby granted, provided that this copyright
- Xnotice appear in all copies and in all supporting documentation. No
- Xrepresentation is made about the suitability of this software for any
- Xpurpose. It is provided "as is" without express or implied warranty.
- X
- X*/
- X
- Xstatic char copyright[] = "\nCopyright (C) 1986 by Jeffrey A. Poskanzer.\n";
- X
- X
- X#include <stdio.h>
- X#include <math.h>
- X#include "tws.h"
- X
- X
- X/* Global defines and declarations. */
- X
- X#define SECSPERMINUTE 60
- X#define SECSPERHOUR (60 * SECSPERMINUTE)
- X#define SECSPERDAY (24 * SECSPERHOUR)
- X
- X#define PI 3.14159
- X
- X#define DEFAULTNUMLINES 23
- X#define MOONSTARTCOL 18
- X#define QUARTERLITLEN 16
- X#define QUARTERLITLENPLUSONE 17
- X
- X/* If you change the aspect ratio, the canned backgrounds won't work. */
- X#define ASPECTRATIO 0.5
- X
- X/* Main program. */
- X
- Xmain( argc, argv, envp )
- Xint argc;
- Xchar *argv[], *envp[];
- X {
- X struct tws t, *twp;
- X char buf[100];
- X int numlines, argi, i;
- X char *usage = "usage: %s [ -l <lines> ] [ <date/time> ]\n";
- X
- X /* Parge args. */
- X argi = 1;
- X /* Check for -l flag. */
- X numlines = DEFAULTNUMLINES;
- X if ( argc - argi >= 1 )
- X {
- X if ( argv[argi][0] == '-' )
- X {
- X if ( argv[argi][1] != 'l' | argv[argi][2] != '\0' )
- X {
- X fprintf( stderr, usage, argv[0] );
- X exit( 1 );
- X }
- X else
- X {
- X if ( argc - argi < 2 )
- X {
- X fprintf( stderr, usage, argv[0] );
- X exit( 1 );
- X }
- X if ( sscanf( argv[argi + 1], "%d", &numlines ) != 1 )
- X {
- X fprintf( stderr, usage, argv[0] );
- X exit( 1 );
- X }
- X argi += 2;
- X }
- X }
- X }
- X
- X /* Figure out what date and time to use. */
- X if ( argc - argi == 0 )
- X {
- X /* No arguments present - use the current date and time. */
- X twscopy( &t, dtwstime( ) );
- X }
- X else if ( argc - argi == 1 || argc - argi == 2 || argc - argi == 3 )
- X {
- X /* One, two, or three args - use them. */
- X strcpy( buf, argv[argi] );
- X if ( argc - argi > 1 )
- X {
- X strcat( buf, " " );
- X strcat( buf, argv[argi + 1] );
- X if ( argc - argi > 2 )
- X {
- X strcat( buf, " " );
- X strcat( buf, argv[argi + 2] );
- X }
- X }
- X twp = dparsetime( buf );
- X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
- X {
- X fprintf( stderr, "illegal date/time: %s\n", buf );
- X exit( 1 );
- X }
- X twscopy( &t, twp );
- X }
- X else
- X {
- X /* Too many args! */
- X fprintf( stderr, usage, argv[0] );
- X exit( 1 );
- X }
- X
- X /* Pseudo-randomly decide what the moon is made of, and print it. */
- X if ( twclock( dtwstime( ) ) % 17 == 3 )
- X putmoon( &t, numlines, "GREENCHEESE" );
- X else
- X putmoon( &t, numlines, "@" );
- X
- X /* All done. */
- X exit( 0 );
- X }
- X
- X
- Xputmoon( t, numlines, atfiller )
- Xstruct tws *t;
- Xint numlines;
- Xchar *atfiller;
- X {
- X struct tws twsanewmoon;
- X long secsynodic = 29*SECSPERDAY + 12*SECSPERHOUR + 44*SECSPERMINUTE + 3;
- X long secdiff, secphase;
- X int atflrlen, atflridx, lin, col, midlin, qlitidx;
- X float angphase, mcap, yrad, xrad, y, xright, xleft;
- X int colright, colleft, i;
- X char c;
- X
- X static char background18[18][37] = {
- X " .----------. ",
- X " .--' o . `--. ",
- X " .'@ @@@@@@ O . . `. ",
- X " .'@@ @@@@@@@@ @@@@ . `. ",
- X " .' . @@@@@@@@ @@@@@@ . `. ",
- X " / @@ o @@@@@@. @@@@ O @\\ ",
- X " |@@@@ @@@@@@ @@| ",
- X " / @@@@@ `.-. . @@@@@@@@ . @@\\",
- X " | @@@@ --`-' . o @@@@@@@ |",
- X " |@ @@ @@@@@@ @@@ |",
- X " \\ @@ @ . () @@ @@@@@ /",
- X " | @ @@@ @@@ @@@ | ",
- X " \\ . @@ @\\ . . @@ o / ",
- X " `. @@@@ _\\ / . o .' ",
- X " `. @@ ()--- .' ",
- X " `. / | . o .' ",
- X " `--./ . .--' ",
- X " `----------' "};
- X
- X static char background19[19][39] = {
- X " .----------. ",
- X " .--' o . `--. ",
- X " .-'@ @@@@@@ O . . `-. ",
- X " .' @@ @@@@@@@@ @@@@ . `. ",
- X " / . @@@@@@@@ @@@@@@ . \\ ",
- X " /@@ o @@@@@@. @@@@ O @\\ ",
- X " /@@@@ @@@@@@ @@@\\ ",
- X " . @@@@@ `.-./ . @@@@@@@@ . @@ .",
- X " | @@@@ --`-' . @@@@@@@ |",
- X " |@ @@ ` o @@@@@@ @@@@ |",
- X " | @@ o @@ @@@@@@ |",
- X " ` . @ @@ () @@@ @@@@ '",
- X " \\ @@ @@@@ . @@ . o / ",
- X " \\ @@@@ @@\\ . o / ",
- X " \\ . @@ _\\ / . .-. / ",
- X " `. . ()--- `-' .' ",
- X " `-. ./ | . o .-' ",
- X " `--./ . .--' ",
- X " `----------' "};
- X
- X static char background23[23][47] = {
- X " .------------. ",
- X " .--' o . . `--. ",
- X " .-' . O . . `-. ",
- X " .-'@ @@@@@@@ . @@@@@ `-. ",
- X " /@@@ @@@@@@@@@@@ @@@@@@@ . \\ ",
- X " ./ o @@@@@@@@@@@ @@@@@@@ . \\. ",
- X " /@@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
- X " /@@@@ . @@@@@@@o @@@@@@@@@@ @@@ \\ ",
- X " |@@@@@ . @@@@@@@@@@@@@ o @@@@| ",
- X " /@@@@@ O `.-./ . @@@@@@@@@@@@ @@ \\",
- X " | @@@@ --`-' o @@@@@@@@ @@@@ |",
- X " |@ @@@ ` o . @@ . @@@@@@@ |",
- X " | @@ @ .-. @@@ @@@@@@@ |",
- X " \\ . @ @@@ `-' . @@@@ @@@@ o /",
- X " | @@ @@@@@ . @@ . | ",
- X " \\ @@@@ @\\@@ / . O . o . / ",
- X " \\ o @@ \\ \\ / . . / ",
- X " `\\ . .\\.-.___ . . .-. /' ",
- X " \\ `-' `-' / ",
- X " `-. o / | o O . .-' ",
- X " `-. / . . .-' ",
- X " `--. . .--' ",
- X " `------------' "};
- X
- X static char background24[24][49] = {
- X " .------------. ",
- X " .---' o . . `---. ",
- X " .-' . O . . `-. ",
- X " .'@ @@@@@@@ . @@@@@ `. ",
- X " .'@@ @@@@@@@@@@@ @@@@@@@ . `. ",
- X " / o @@@@@@@@@@@ @@@@@@@ . \\ ",
- X " /@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
- X " /@@@ . @@@@@@@o @@@@@@@@@@ @@@ \\ ",
- X " /@@@@@ . @@@@@@@@@@@@@ o @@@@ \\ ",
- X " |@@@@ O `.-./ . @@@@@@@@@@@@ @@ | ",
- X " / @@@@ --`-' o @@@@@@@@ @@@@ \\",
- X " |@ @@@ @ ` . @@ @@@@@@@ |",
- X " | @ o @ @@@@@@@ |",
- X " \\ @@ .-. @@@ @@@@ o /",
- X " | . @ @@@ `-' . @@@@ | ",
- X " \\ @@ @@@@@ . @@ . / ",
- X " \\ @@@@ @\\@@ / . O . o . / ",
- X " \\ o @@ \\ \\ / . . / ",
- X " \\ . .\\.-.___ . . .-. / ",
- X " `. `-' `-' .' ",
- X " `. o / | o O . .' ",
- X " `-. / . . .-' ",
- X " `---. . .---' ",
- X " `------------' "};
- X static char background29[29][59] = {
- X " .--------------. ",
- X " .---' o . `---. ",
- X " .-' . O . . `-. ",
- X " .-' @@@@@@ . `-. ",
- X " .'@@ @@@@@@@@@@@ @@@@@@@ . `. ",
- X " .'@@@ @@@@@@@@@@@@@@ @@@@@@@@@ `. ",
- X " /@@@ o @@@@@@@@@@@@@@ @@@@@@@@@ O \\ ",
- X " / @@@@@@@@@@@@@@ @ @@@@@@@@@ @@ . \\ ",
- X " /@ o @@@@@@@@@@@ . @@ @@@@@@@@@@@ @@ \\ ",
- X " /@@@ . @@@@@@ o @ @@@@@@@@@@@@@ o @@@@ \\ ",
- X " /@@@@@ @ . @@@@@@@@@@@@@@ @@@@@ \\ ",
- X " |@@@@@ O `.-./ . . @@@@@@@@@@@@@ @@@ | ",
- X " / @@@@@ --`-' o @@@@@@@@@@@ @@@ . \\",
- X " |@ @@@@ . @ @ ` @ @@ . @@@@@@ |",
- X " | @@ o @@ . @@@@@@ |",
- X " | . @ @ @ o @@ o @@@@@@. |",
- X " \\ @ @ @ .-. @@@@ @@@ /",
- X " | @ @ @ `-' . @@@@ . . | ",
- X " \\ . o @ @@@@ . @@ . . / ",
- X " \\ @@@ @@@@@@ . o / ",
- X " \\ @@@@@ @@\\@@ / O . / ",
- X " \\ o @@@ \\ \\ / __ . . .--. / ",
- X " \\ . . \\.-.--- `--' / ",
- X " `. `-' . .' ",
- X " `. o / | ` O . .' ",
- X " `-. / | o .-' ",
- X " `-. . . .-' ",
- X " `---. . .---' ",
- X " `--------------' "};
- X
- X static char qlits[8][16] = {
- X "New Moon + ",
- X "First Quarter +",
- X "Full Moon + ",
- X "Last Quarter + ",
- X "First Quarter -",
- X "Full Moon - ",
- X "Last Quarter - ",
- X "New Moon - " };
- X
- X
- X /* Find the length of the atfiller string. */
- X atflrlen = strlen( atfiller );
- X
- X /* Convert a new moon date from a string to a tws. */
- X twscopy( &twsanewmoon, dparsetime( "05jan81 23:24:00 PST" ) );
- X
- X /* Subtract the new moon date from the desired date to get the interval
- X since the new moon. */
- X secdiff = twsubtract( t, &twsanewmoon );
- X
- X /* Figure out the phase - the interval since the last new moon. */
- X secphase = secdiff % secsynodic;
- X if ( secphase < 0L )
- X secphase += secsynodic; /* fucking mathematician language designers */
- X angphase = (float) secphase / (float) secsynodic * 2.0 * PI;
- X mcap = -cos( angphase );
- X
- X /* Figure out how big the moon is. */
- X yrad = numlines / 2.0;
- X xrad = yrad / ASPECTRATIO;
- X
- X /* Figure out some other random stuff. */
- X midlin = numlines / 2;
- X qlitidx = angphase / PI * 2.0;
- X
- X /* Now output the moon, a slice at a time. */
- X atflridx = 0;
- X for ( lin = 0; lin < numlines; lin = lin + 1 )
- X {
- X /* Compute the edges of this slice. */
- X y = lin + 0.5 - yrad;
- X xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) );
- X xleft = -xright;
- X if ( angphase >= 0.0 && angphase < PI )
- X xleft = mcap * xleft;
- X else
- X xright = mcap * xright;
- X colleft = (int) (xrad + 0.5) + (int) (xleft + 0.5);
- X colright = (int) (xrad + 0.5) + (int) (xright + 0.5);
- X
- X /* Now output the slice. */
- X for ( i = 0; i < colleft; i++ )
- X putchar( ' ' );
- X for ( col = colleft; col <= colright; col = col + 1 )
- X {
- X switch ( numlines )
- X {
- X case 18:
- X c = background18[lin][col];
- X break;
- X case 19:
- X c = background19[lin][col];
- X break;
- X case 23:
- X c = background23[lin][col];
- X break;
- X case 24:
- X c = background24[lin][col];
- X break;
- X case 29:
- X c = background29[lin][col];
- X break;
- X default:
- X c = '@';
- X }
- X if ( c != '@' )
- X putchar( c );
- X else
- X {
- X putchar( atfiller[atflridx] );
- X atflridx = ( atflridx + 1 ) % atflrlen;
- X }
- X }
- X
- X /* Output the end-of-line information, if any. */
- X if ( lin == midlin - 2 )
- X {
- X putchar( '\t' );
- X putchar( '\t' );
- X fputs( qlits[qlitidx], stdout );
- X }
- X else if ( lin == midlin - 1)
- X {
- X putchar( '\t' );
- X putchar( '\t' );
- X putseconds( secphase % (secsynodic / 4) );
- X }
- X else if ( lin == midlin )
- X {
- X putchar( '\t' );
- X putchar( '\t' );
- X fputs( qlits[qlitidx + 4], stdout );
- X }
- X else if ( lin == midlin + 1 )
- X {
- X putchar( '\t' );
- X putchar( '\t' );
- X putseconds( (secsynodic - secphase) % (secsynodic / 4) );
- X }
- X
- X putchar( '\n' );
- X }
- X
- X }
- X
- X
- Xputseconds( secs )
- Xlong secs;
- X {
- X long days, hours, minutes;
- X
- X days = secs / SECSPERDAY;
- X secs = secs - days * SECSPERDAY;
- X hours = secs / SECSPERHOUR;
- X secs = secs - hours * SECSPERHOUR;
- X minutes = secs / SECSPERMINUTE;
- X secs = secs - minutes * SECSPERMINUTE;
- X
- X printf( "%ld %2ld:%02ld:%02ld", days, hours, minutes, secs );
- X }
- SHAR_EOF
- if test 12899 -ne "`wc -c < 'phoon.c'`"
- then
- echo shar: error transmitting "'phoon.c'" '(should have been 12899 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'phoon.man'" '(696 characters)'
- if test -f 'phoon.man'
- then
- echo shar: will not over-write existing file "'phoon.man'"
- else
- sed 's/^X//' << \SHAR_EOF > 'phoon.man'
- X.TH phoon 1 "08 November 1986"
- X.SH NAME
- Xphoon \- show the PHase of the mOON
- X.SH SYNOPSIS
- X.in +.5i
- X.ti -.5i
- Xphoon \%[ -l <lines> ] \%[ <date> ]
- X.in -.5i
- X.SH DESCRIPTION
- X.I Phoon
- Xdisplays the phase of the moon, either currently
- Xor at a specified date / time.
- XUnlike other such programs, which just tell you how long since first quarter
- Xor something like that, phoon
- X.I shows
- Xyou the phase with a cute little picture.
- XYou can vary the size of the picture with the -l flag, but only some
- Xsizes have pictures defined - other sizes use @'s.
- X.SH "SEE\ ALSO"
- X.IR deltime(1),
- X.IR libtws(3)
- X.SH AUTHOR
- XJef Poskanzer
- X.SH BUGS
- XThe algorithm for determining the phase is very simple, but not very
- Xaccurate.
- SHAR_EOF
- if test 696 -ne "`wc -c < 'phoon.man'`"
- then
- echo shar: error transmitting "'phoon.man'" '(should have been 696 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'tws.h'" '(2290 characters)'
- if test -f 'tws.h'
- then
- echo shar: will not over-write existing file "'tws.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'tws.h'
- X/* tws.h - header file for libtws date/time library */
- X
- X
- X/* Definition of the tws data structure. */
- X
- Xstruct tws {
- X int tw_sec;
- X int tw_min;
- X int tw_hour;
- X
- X int tw_mday;
- X int tw_mon;
- X int tw_year;
- X
- X int tw_wday;
- X int tw_yday;
- X
- X int tw_zone;
- X
- X long tw_clock;
- X
- X int tw_flags;
- X#define TW_NULL 0x0000
- X#define TW_SDAY 0x0007 /* how day-of-week was determined */
- X#define TW_SNIL 0x0000 /* not given */
- X#define TW_SEXP 0x0001 /* explicitly given */
- X#define TW_SIMP 0x0002 /* implicitly given */
- X#define TW_DST 0x0010 /* daylight savings time */
- X#define TW_ZONE 0x0020 /* use numeric timezones only */
- X#define TW_JUNK 0x0040 /* date string contained junk */
- X};
- X
- X
- X/* Declarations of routines. */
- X
- Xvoid twscopy( );
- X /* twscopy( &totws, &fromtws ) copies a tws */
- Xint twsort( );
- X /* twsort( &tws1, &tws2 ) compares two tws's: 1 means tws1 is
- X later; -1 means tws1 is earlier; 0 means they are equal */
- Xlong twclock( );
- X /* twclock( &tws ) turns a tws into a time(3)-style clock value */
- Xlong twjuliandate( );
- X /* twjuliandate( &tws ) returns the Julian day number of a tws */
- Xlong twsubtract( );
- X /* twsubtract( &tws1, &tws2 ) returns seconds of difference */
- X
- X/* These routines are functionally similar to the ctime(3) routines
- X in the standard Unix library. */
- Xchar *dctime( );
- X /* dctime( &tws ) returns a string for the date/time passed in */
- Xstruct tws *dlocaltime( );
- X /* dlocaltime( &clock ) turns a time(3) clock value into a tws */
- Xstruct tws *dgmtime( );
- X /* dgmtime( &clock ) turns a time(3) clock value into a tws */
- Xchar *dasctime( );
- X /* dasctime( &tws, flags ) turns a tws into a string */
- Xchar *dtimezone( );
- X /* dtimezone( offset, flags ) returns the name of the time zone */
- X
- Xchar *dtimenow( );
- X /* dtimenow( ) returns a string for the current date/time */
- X
- Xstruct tws *dparsetime( );
- X /* dparsetime( &str ) turns a string into a tws */
- X
- Xstruct tws *dtwstime( );
- X /* dtwstime( ) returns a tws for the current date/time */
- X
- X#ifdef ATZ
- X#define dtime(cl) dasctime( dlocaltime( cl ), TW_NULL )
- X#else ATZ
- X#define dtime(cl) dasctime( dlocaltime( cl ), TW_ZONE )
- X#endif ATZ
- X
- X#define dtwszone(tw) dtimezone( tw -> tw_zone, tw -> tw_flags )
- X
- X
- Xextern char *tw_dotw[], *tw_ldotw[], *tw_moty[];
- SHAR_EOF
- if test 2290 -ne "`wc -c < 'tws.h'`"
- then
- echo shar: error transmitting "'tws.h'" '(should have been 2290 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-